package com.zenithmind.version.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.version.mapper.TagMapper;
import com.zenithmind.version.pojo.domain.Tag;
import com.zenithmind.version.pojo.dto.TagCreateDTO;
import com.zenithmind.version.pojo.dto.TagUpdateDTO;
import com.zenithmind.version.pojo.query.TagQueryDTO;
import com.zenithmind.version.pojo.vo.TagVO;
import com.zenithmind.version.service.TagService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 标签服务实现类
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TagServiceImpl extends ServiceImpl<TagMapper, Tag> implements TagService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TagVO createTag(TagCreateDTO createDTO) {
        log.info("创建标签: {}", createDTO.getTagName());
        
        // 检查标签名称是否存在
        if (checkTagNameExists(createDTO.getRepositoryId(), createDTO.getTagName(), null)) {
            throw new RuntimeException("标签名称已存在");
        }
        
        Tag tag = new Tag();
        BeanUtils.copyProperties(createDTO, tag);
        tag.setCreatorId(UserContext.getUserId());
        tag.setCreateTime(LocalDateTime.now());
        tag.setUpdateTime(LocalDateTime.now());
        
        // 设置版本序号
        if (createDTO.getTagType() == 1 && createDTO.getVersionOrder() == null) {
            Integer maxVersionOrder = baseMapper.getMaxVersionOrder(createDTO.getRepositoryId());
            tag.setVersionOrder(maxVersionOrder + 1);
        }
        
        save(tag);
        
        return convertToVO(tag);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateTag(String id, TagUpdateDTO updateDTO) {
        log.info("更新标签: {}", id);
        
        Tag tag = getById(id);
        if (tag == null) {
            throw new RuntimeException("标签不存在");
        }
        
        // 检查标签名称是否存在
        if (updateDTO.getTagName() != null && 
            checkTagNameExists(tag.getRepositoryId(), updateDTO.getTagName(), id)) {
            throw new RuntimeException("标签名称已存在");
        }
        
        BeanUtils.copyProperties(updateDTO, tag);
        tag.setUpdateTime(LocalDateTime.now());
        
        return updateById(tag);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteTag(String id) {
        log.info("删除标签: {}", id);
        
        Tag tag = getById(id);
        if (tag == null) {
            throw new RuntimeException("标签不存在");
        }
        
        tag.setIsDeleted(1);
        tag.setUpdateTime(LocalDateTime.now());
        
        return updateById(tag);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchDeleteTags(List<String> ids) {
        log.info("批量删除标签: {}", ids);
        
        return baseMapper.batchDeleteTags(ids) > 0;
    }

    @Override
    public IPage<TagVO> getTagPage(TagQueryDTO queryDTO) {
        log.info("分页查询标签");
        
        Page<TagVO> page = queryDTO.toPage();
        
        return baseMapper.selectTagPageWithDetails(
                page,
                queryDTO.getRepositoryId(),
                queryDTO.getTagType(),
                queryDTO.getCreatorId()
        );
    }

    @Override
    public TagVO getTagDetail(String id) {
        log.info("获取标签详情: {}", id);
        
        return baseMapper.selectTagDetail(id);
    }

    @Override
    public List<TagVO> getRepositoryTags(String repositoryId, Integer tagType, Integer limit) {
        log.info("获取仓库标签列表: repositoryId={}, tagType={}", repositoryId, tagType);
        
        return baseMapper.selectRepositoryTags(repositoryId, tagType, limit);
    }

    @Override
    public TagVO getTagByName(String repositoryId, String tagName) {
        log.info("根据名称获取标签: repositoryId={}, tagName={}", repositoryId, tagName);
        
        return baseMapper.selectTagByName(repositoryId, tagName);
    }

    @Override
    public List<TagVO> getVersionTags(String repositoryId, Integer limit) {
        log.info("获取版本标签列表: repositoryId={}", repositoryId);
        
        return baseMapper.selectVersionTags(repositoryId, limit);
    }

    @Override
    public List<TagVO> getReleaseTags(String repositoryId, Integer limit) {
        log.info("获取发布标签列表: repositoryId={}", repositoryId);
        
        return baseMapper.selectReleaseTags(repositoryId, limit);
    }

    @Override
    public TagVO getLatestVersionTag(String repositoryId) {
        log.info("获取最新版本标签: repositoryId={}", repositoryId);
        
        return baseMapper.selectLatestVersionTag(repositoryId);
    }

    @Override
    public List<TagVO> getCommitTags(String commitId) {
        log.info("获取提交的标签列表: commitId={}", commitId);
        
        return baseMapper.selectCommitTags(commitId);
    }

    @Override
    public List<TagVO> searchTags(String repositoryId, String keyword, Integer tagType, Integer limit) {
        log.info("搜索标签: repositoryId={}, keyword={}", repositoryId, keyword);
        
        return baseMapper.searchTags(repositoryId, keyword, tagType, limit);
    }

    @Override
    public List<TagVO> getUserTags(String creatorId, String repositoryId, Integer limit) {
        log.info("获取用户创建的标签: creatorId={}, repositoryId={}", creatorId, repositoryId);
        
        return baseMapper.selectUserTags(creatorId, repositoryId, limit);
    }

    @Override
    public Object compareTagDifferences(String repositoryId, String fromTag, String toTag) {
        log.info("比较标签差异: repositoryId={}, fromTag={}, toTag={}", repositoryId, fromTag, toTag);
        
        return baseMapper.compareTagDifferences(repositoryId, fromTag, toTag);
    }

    @Override
    public List<Object> getCommitsBetweenTags(String repositoryId, String fromTag, String toTag) {
        log.info("获取标签之间的提交列表: repositoryId={}, fromTag={}, toTag={}", repositoryId, fromTag, toTag);
        
        return baseMapper.selectCommitsBetweenTags(repositoryId, fromTag, toTag);
    }

    @Override
    public Object getTagStatistics(String repositoryId) {
        log.info("获取标签统计信息: repositoryId={}", repositoryId);
        
        return baseMapper.selectTagStatistics(repositoryId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TagVO copyTagToCommit(String sourceTagId, String targetCommitId, String newTagName, String userId) {
        log.info("复制标签到其他提交: sourceTagId={}, targetCommitId={}, newTagName={}", sourceTagId, targetCommitId, newTagName);
        
        String newTagId = baseMapper.copyTagToCommit(sourceTagId, targetCommitId, newTagName, userId);
        Tag newTag = getById(newTagId);
        
        return convertToVO(newTag);
    }

    @Override
    public Boolean checkTagNameExists(String repositoryId, String tagName, String excludeId) {
        log.info("检查标签名称是否存在: repositoryId={}, tagName={}", repositoryId, tagName);
        
        return baseMapper.checkTagNameExists(repositoryId, tagName, excludeId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TagVO createVersionTag(String repositoryId, String commitId, String version, String description, String userId) {
        log.info("创建版本标签: repositoryId={}, commitId={}, version={}", repositoryId, commitId, version);
        
        TagCreateDTO createDTO = new TagCreateDTO();
        createDTO.setRepositoryId(repositoryId);
        createDTO.setCommitId(commitId);
        createDTO.setTagName(version);
        createDTO.setDescription(description);
        createDTO.setTagType(1); // 版本标签
        
        return createTag(createDTO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TagVO createReleaseTag(String repositoryId, String commitId, String releaseName, String description, String userId) {
        log.info("创建发布标签: repositoryId={}, commitId={}, releaseName={}", repositoryId, commitId, releaseName);
        
        TagCreateDTO createDTO = new TagCreateDTO();
        createDTO.setRepositoryId(repositoryId);
        createDTO.setCommitId(commitId);
        createDTO.setTagName(releaseName);
        createDTO.setDescription(description);
        createDTO.setTagType(2); // 发布标签
        
        return createTag(createDTO);
    }

    @Override
    public Object getTagReleaseNotes(String tagId) {
        log.info("获取标签发布说明: tagId={}", tagId);
        
        Tag tag = getById(tagId);
        return tag != null ? tag.getReleaseNotes() : null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateTagReleaseNotes(String tagId, String releaseNotes, String userId) {
        log.info("更新标签发布说明: tagId={}, userId={}", tagId, userId);
        
        Tag tag = getById(tagId);
        if (tag == null) {
            throw new RuntimeException("标签不存在");
        }
        
        tag.setReleaseNotes(releaseNotes);
        tag.setUpdateTime(LocalDateTime.now());
        
        return updateById(tag);
    }

    /**
     * 转换为VO
     */
    private TagVO convertToVO(Tag tag) {
        TagVO vo = new TagVO();
        BeanUtils.copyProperties(tag, vo);

        // 补充字段转换
        if (tag.getCreateTime() != null) {
            vo.setCreateTime(tag.getCreateTime());
        }
        if (tag.getUpdateTime() != null) {
            vo.setUpdateTime(tag.getUpdateTime());
        }

        return vo;
    }
}
